package cn.funnymap.lgis.mp.ltree.mapper;

import cn.funnymap.lgis.mp.ltree.pojo.entity.LTreeBaseEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * @author liby
 */
public interface LTreeBaseMapper<E extends LTreeBaseEntity> extends BaseMapper<E>{
    @Select("select * from ${tableName} where is_deleted = false and path ~ (select concat(path, '.*') from ${tableName} " +
            "where id = #{id})::lquery or id = #{id} order by sort")
    List<E> getSelfAndChildrenById(@Param("id") String id, @Param("tableName") String tableName);

    @Select("select * from ${tableName} where is_deleted = false and path ~ (#{path} || '.*{1}')::lquery;")
    List<E> queryNextLevelNodesByPath(@Param("path") String path, @Param("tableName") String tableName);

    @Delete("delete from ${tableName} where path <@ (select path from ${tableName} where id = #{id})")
    void deleteByIdAndChildren(@Param("id") String id, @Param("tableName") String tableName);

    @Select("select * from ${tableName}  where path = (select subpath(path,0,nlevel(path)-1) from ${tableName} " +
            " where id =#{id} and is_deleted = false);")
    E getParentByChildId(@Param("id") String id, @Param("tableName") String tableName);

    @Select("select * from ${tableName} where is_deleted = false and path ~ (select concat(path, '.*') " +
            "from ${tableName} where id = #{id})::lquery and id != #{id} order by path, sort")
    List<E> getNoSelfAndChildrenById(@Param("id") String id, @Param("tableName") String tableName);

    @Select("select * from ${tableName} where subpath(path, 0, nlevel(path) - 1) = " +
            "(select subpath(path, 0, nlevel(path) - 1) from ${tableName} " +
            "where id = #{id}) and sort >= #{sort} and is_deleted = false order by sort;")
    List<E> queryBrotherNodesGTSort(@Param("id") String id, @Param("sort") Integer sort, @Param("tableName") String tableName);

    @Select("select * from ${tableName} where subpath(path, 0, nlevel(path) - 1) = " +
            "(select subpath(path, 0, nlevel(path) - 1) from ${tableName} " +
            "where id = #{id}) and sort between #{minSort} and #{maxSort} and id != #{id} and is_deleted = false order by sort;")
    List<E> queryBrotherNodesNoSelfBetweenSort(@Param("id") String id, @Param("minSort") Integer minSort,
                                               @Param("maxSort") Integer maxSort, @Param("tableName") String tableName);

    @Update("update ${tableName} set is_deleted = true where is_deleted = false " +
            "and path ~ (select concat(path, '.*') from t_ltree where id = #{id})::lquery or id = #{id};")
    void logicDeleteNodeById(@Param("id") String id, @Param("tableName") String tableName);
}